package cn.edu.sjtu.process_management.controller;

import cn.edu.sjtu.process_management.model.History;
import cn.edu.sjtu.process_management.model.Process;
import cn.edu.sjtu.process_management.model.Result;
import cn.edu.sjtu.process_management.model.Role;
import cn.edu.sjtu.process_management.service.AsyncService;
import cn.edu.sjtu.process_management.service.HistoryService;
import cn.edu.sjtu.process_management.service.ProcessService;
import cn.edu.sjtu.process_management.util.JWTUtil;
import cn.edu.sjtu.process_management.util.ResultUtil;
import cn.edu.sjtu.process_management.util.StrConvertUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.Optional;

/**
 * @author loumoon
 * @date 2019-11-01 15:03
 */
@RestController
public class ProcessController {

    @Autowired
    private ProcessService processService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private AsyncService asyncService;

    /*创建流程*/
    @RequestMapping(value = "/process", method = RequestMethod.POST)
    public Result createProcess(@RequestHeader("Authorization") String token, @RequestParam("name") String name, @RequestParam("file") MultipartFile file) {
        String owner = JWTUtil.decodeUserId(token);

        String bpmn = StrConvertUtil.multiFileToStr(file);
        processService.createProcess(name, owner, bpmn);
        return ResultUtil.success();
    }

    /*更新流程bpmn*/
    @RequestMapping(value = "/process/bpmn", method = RequestMethod.PUT)
    public Result updateProcessBpmn(@RequestHeader("Authorization") String token, @RequestParam("name") String name, @RequestParam("file") MultipartFile file) {
        String owner = JWTUtil.decodeUserId(token);

        String bpmn = StrConvertUtil.multiFileToStr(file);
        processService.updateProcessBpmn(name, owner, bpmn);
        return ResultUtil.success();
    }

    /*更新流程状态*/
    @RequestMapping(value = "/process/status", method = RequestMethod.PUT)
    public Result updateProcessStatus(@RequestHeader("Authorization") String token, @RequestParam("name") String name, @RequestParam("status") boolean status) {
        String owner = JWTUtil.decodeUserId(token);

        processService.updateProcessStatus(name, owner, status);
        return ResultUtil.success();
    }

    /*更新流程名称*/
    @RequestMapping(value = "/process/name", method = RequestMethod.PUT)
    public Result updateProcessName(@RequestHeader("Authorization") String token, @RequestParam("oldName") String oldName, @RequestParam("newName") String newName) {
        String owner = JWTUtil.decodeUserId(token);

        processService.updateProcessName(oldName, owner, newName);
        return ResultUtil.success();
    }

    /*查找流程*/
    @RequestMapping(value = "/process", method = RequestMethod.GET)
    public Result findProcesses(@RequestHeader("Authorization") String token, @RequestParam("processId") Optional<String> processId) {
        String owner = JWTUtil.decodeUserId(token);
        Integer role = JWTUtil.decodeRole(token); // 请求者的角色

        if (processId.isPresent()) { // 根据processId查找指定流程
            if (role == Role.MANAGER.ordinal()) {
                return ResultUtil.success(processService.findProcess(processId.get()));
            } else {
                return ResultUtil.success(processService.findProcess(processId.get(), owner));
            }
        } else {
            if (role == Role.MANAGER.ordinal()) { // 对管理人员返回所有流程
                return ResultUtil.success(processService.findAllProcesses());
            } else { // 对流程人员返回其拥有的流程
                return ResultUtil.success(processService.findOwnedProcesses(owner));
            }
        }
    }

    /*删除流程*/
    @RequestMapping(value = "/process", method = RequestMethod.DELETE)
    public Result deleteProcess(@RequestHeader("Authorization") String token, @RequestParam("processId") String processId) {
        String owner = JWTUtil.decodeUserId(token);
        Integer role = JWTUtil.decodeRole(token);

        if (role == Role.MANAGER.ordinal()) {
            processService.deleteProcess(processId);
        } else {
            processService.deleteProcess(processId, owner);
        }

        return ResultUtil.success();
    }

    /*执行流程*/
    @RequestMapping(value = "/process/execution", method = RequestMethod.POST)
    public Result executeProcess(@RequestHeader("Authorization") String token, @RequestParam("name") String name, @RequestParam("file") MultipartFile file) {
        String owner = JWTUtil.decodeUserId(token);
        String bpmnInstance = StrConvertUtil.multiFileToStr(file);

        Process process = processService.findProcess(name, owner);
        History history = historyService.createHistory(process, bpmnInstance);

        asyncService.executeProcess(history); // 异步执行流程

        return ResultUtil.success(history);
    }

}
